import Line from '../elements/line';
import Bezier from '../elements/bezier';
import Circle from '../elements/circle';

import * as _ from '../utils';

export default {
    line: function (serie, opts) {
        let elements = [];
        let data = _.getObjProperty(serie, 'data', []);
        let smooth = _.getObjProperty(serie, 'smooth', false);
        let symbol = _.getObjProperty(serie, 'symbol', 'emptyCircle');
        let origin = _.getObjProperty(opts, 'origin', {});
        let xAxis = _.getObjProperty(opts, 'xAxis', []);
        let xAxisData = xAxis.data;
        let yAxisWidth = xAxis.yAxisWidth;

        let yAxis = _.getObjProperty(opts, 'yAxis', {});
        let yAxisData = yAxis.data;
        let xAxisLen = yAxis.xAxisLen;

        let yAxisLen = yAxisData.length;
        let yMax = yAxisData[yAxisLen - 1];

        let x = origin.x;
        let y = origin.y;
        let w = origin.w;
        let h = origin.h;

        let offsetX = x + yAxisWidth;
        let offsetY = y;
        let color = serie.color;
        let lineWidth = opts.lineWidth || 2;
        let dataLen = data.length;
        let xLen = parseInt((w - yAxisWidth) / xAxisLen);

        let lines = [];
        let circles = [];
        for (let i = 0; i < xAxisLen; i++) {
            if (i < dataLen) {
                let val1 = data[i];
                let x1 = parseInt(xLen / 2) + offsetX + xLen * i;
                let y1 = parseInt(((yMax - val1) * h) / yMax) + offsetY;

                circles.push([
                    {
                        x: x1,
                        y: y1,
                        r: lineWidth,
                    },
                ]);
                if (i > 0) {
                    let val2 = data[i - 1];
                    let x2 = x1 - xLen;
                    let y2 = parseInt(((yMax - val2) * h) / yMax) + offsetY;
                    lines.push([
                        {
                            x: x2,
                            y: y2,
                        },
                        {
                            x: x1,
                            y: y1,
                        },
                    ]);
                }
            }
        }

        let linesLen = lines.length;
        for (let i = 0; i < linesLen; i++) {
            let points = lines[i];
            let style = {
                strokeStyle: color,
                lineWidth: lineWidth,
                zIndex: 100,
            };
            let action = {
                beginPath: i == 0,
                save: i == 0,
                restore: i == linesLen - 1,
                stroke: i == linesLen - 1,
            };

            let line = new Line({
                points,
                style,
                action,
            });
            if (smooth) {
                let s_x = points[0].x;
                let s_y = points[0].y;
                let e_x = points[1].x;
                let e_y = points[1].y;

                let cp1 = {
                    x: s_x,
                    y: s_y,
                };
                if (0 < i) {
                    let x = (s_x + e_x) / 2;
                    let y = s_y;

                    let pre_p = lines[i - 1];
                    // let pre_x = pre_p[0].x;
                    let pre_y = pre_p[0].y;

                    let by1 = e_y - s_y;
                    let by2 = s_y - pre_y;

                    let sup = by1 * by2;
                    if (sup > 0) {
                        let s = (by2 - by1) / (by2 + by1);
                        y = (s_y + e_y) / 2;
                        if (s > 0) {
                            x = s_x + (xLen * (1 - s)) / 2;
                        } else {
                            y = (s_y + e_y) / 2 - ((by2 - by1) * s) / 2;
                        }
                    }
                    cp1 = { x, y };
                }
                points.push(cp1);
                let cp2 = {
                    x: e_x,
                    y: e_y,
                };
                if (i < linesLen - 1) {
                    let x = (s_x + e_x) / 2;
                    let y = e_y;

                    let next_p = lines[i + 1];
                    // let next_x = next_p[1].x;
                    let next_y = next_p[1].y;

                    let by1 = e_y - s_y;
                    let by2 = next_y - e_y;
                    let sup = by1 * by2;
                    if (sup > 0) {
                        let s = (by2 - by1) / (by2 + by1);
                        y = (s_y + e_y) / 2;
                        if (s > 0) {
                            x = e_x - (xLen * (1 - s)) / 2;
                        } else {
                            y = (s_y + e_y) / 2 + ((by2 - by1) * s) / 2;
                        }
                    }
                    cp2 = { x, y };
                }
                points.push(cp2);
                line = new Bezier({
                    points,
                    style,
                    action,
                });
            }
            elements.push(line);
        }

        let circlesLen = circles.length;
        for (let i = 0; i < circlesLen; i++) {
            let points = circles[i];
            let style = {
                strokeStyle: color,
                lineWidth: lineWidth,
                zIndex: 101,
            };
            let action = { closePath: true };
            let circle = new Circle({
                points,
                style,
                action,
            });
            if (symbol !== 'none') {
                elements.push(circle);
            }
        }

        return elements;
    },
};
